home *** CD-ROM | disk | FTP | other *** search
Text File | 1991-05-01 | 13.6 KB | 498 lines | [TEXT/MPS ] |
- // UIterator.cp
- // Copyright © 1986-1991 by Apple Computer, Inc. All rights reserved.
-
- #ifndef __UMACAPPUTILITIES__
- #include <UMacAppUtilities.h>
- #endif
-
- #ifndef __UOBJECT__
- #include <UObject.h>
- #endif
-
- #ifndef __ULIST__
- #include <UList.h>
- #endif
-
- #ifndef __UITERATOR__
- #include <UIterator.h>
- #endif
-
-
- // The CIterator methods should be defined as pure abstract methods. However
- // doing so introduces a problem with determing the "key function" of the class
- // and leads to duplicate definitions of the VTables in all files that include
- // iterators. So for the time being use empty implementations
-
- //--------------------------------------------------------------------------------------------------
- #pragma segment IteratorRes
-
- Boolean CIterator::More()
- {
- return FALSE;
- }
-
- //--------------------------------------------------------------------------------------------------
- #pragma segment IteratorRes
-
- void CIterator::Reset()
- {
- }
-
- //--------------------------------------------------------------------------------------------------
- #pragma segment IteratorRes
-
- void CIterator::Advance()
- {
- }
-
- //--------------------------------------------------------------------------------------------------
- #pragma segment IteratorRes
-
- CArrayIterator* CArrayIterator::AppendToList(CArrayIterator* toList)
- {
- if (toList)
- {
- fNextLink = toList->fNextLink;
- fPreviousLink = toList;
-
- fNextLink->fPreviousLink = this;
- toList->fNextLink = this;
- }
- return this;
- }
-
- //--------------------------------------------------------------------------------------------------
- #pragma segment IteratorRes
-
- CArrayIterator* CArrayIterator::RemoveFromList()
- {
- CArrayIterator * returnLink;
-
- if (fNextLink == this)
- returnLink = NULL;
- else
- returnLink = fNextLink;
-
- fNextLink->fPreviousLink = fPreviousLink;
- fPreviousLink->fNextLink = fNextLink;
-
- fNextLink = this;
- fPreviousLink = this;
-
- return returnLink;
- }
-
- //--------------------------------------------------------------------------------------------------
- #pragma segment IteratorRes
-
- CArrayIterator::CArrayIterator(TDynamicArray* itsDynamicArray,
- ArrayIndex itsLowBound,
- ArrayIndex itsHighBound,
- Boolean itsForward)
- {
- if (itsDynamicArray)
- IArrayIterator(itsDynamicArray, itsLowBound, itsHighBound, itsForward);
- else
- IArrayIterator();
- }
-
- //--------------------------------------------------------------------------------------------------
- #pragma segment IteratorRes
-
- CArrayIterator::CArrayIterator(TDynamicArray* itsDynamicArray,
- Boolean itsForward)
- {
- if (itsDynamicArray)
- {
- ArrayIndex highBound = itsDynamicArray->GetSize();
-
- IArrayIterator(itsDynamicArray, Min(1, highBound), highBound, itsForward);
- }
- else
- IArrayIterator();
- }
-
- //--------------------------------------------------------------------------------------------------
- #pragma segment IteratorRes
-
- CArrayIterator::CArrayIterator(TDynamicArray* itsDynamicArray)
- {
- if (itsDynamicArray)
- {
- ArrayIndex highBound = itsDynamicArray->GetSize();
-
- IArrayIterator(itsDynamicArray, Min(1, highBound), highBound, kIterateForward);
- }
- else
- IArrayIterator();
- }
-
- //--------------------------------------------------------------------------------------------------
- #pragma segment IteratorRes
-
- void CArrayIterator::IArrayIterator(TDynamicArray* itsDynamicArray,
- ArrayIndex itsLowBound,
- ArrayIndex itsHighBound,
- Boolean itsForward)
- {
- fNextLink = this;
- fPreviousLink = this;
- fHighBound = MinMax(kEmptyIndex, itsHighBound, itsDynamicArray->GetSize());
- fLowBound = MinMax(kEmptyIndex, itsLowBound, fHighBound);
- fIterateForward = itsForward;
- fDynamicArray = itsDynamicArray;
-
- // set the initial value of the current index based on the direction of the iteration.
- if (fIterateForward)
- fCurrentIndex = fLowBound;
- else
- fCurrentIndex = fHighBound;
-
- // Make sure that the fCurrentIndex counter and Iteration direction flag from
- // an Iterator are used so that the fCurrentIndex counter can be "bent" if anyone
- // else deletes or inserts elements while the iteration is in progress. Pretty slick, eh?
-
- // link me in to the list of iterations in progress
- fDynamicArray->fIteratorPtr = this->AppendToList(fDynamicArray->fIteratorPtr);
-
- // Setup the FailInfo to catch any failures while this object is in scope
- // giving control to the HandleFailure method
- CatchFailures(this->fFailInfo, (CatchFailuresType) & CArrayIterator::HandleFailure, this);
- }
-
- //--------------------------------------------------------------------------------------------------
- #pragma segment IteratorRes
-
- void CArrayIterator::IArrayIterator()
- {
- fNextLink = this;
- fPreviousLink = this;
- fHighBound = kEmptyIndex;
- fLowBound = kEmptyIndex;
- fCurrentIndex = kEmptyIndex;
- fIterateForward = kIterateForward;
- fDynamicArray = NULL;
- }
-
- //--------------------------------------------------------------------------------------------------
- #pragma segment IteratorRes
-
- CArrayIterator::~CArrayIterator()
- {
- if (fDynamicArray)
- {
- // Remove our entry in the failure handling system as we are going out of scope
- Success(fFailInfo);
-
- fDynamicArray->fIteratorPtr = this->RemoveFromList();
-
- // Check if there is a pending free request that couldn't be honored because we were
- // iterating and if so… be free!
- if (fDynamicArray->fFreeRequested &&!fDynamicArray->fIteratorPtr)
- fDynamicArray->Free();
- }
- }
-
- //--------------------------------------------------------------------------------------------------
- #pragma segment IteratorRes
-
- void CArrayIterator::Advance(void)
- {
- if (fIterateForward)
- {
- if (fCurrentIndex < fHighBound)
- ++fCurrentIndex;
- else
- fCurrentIndex = kEmptyIndex;
- }
- else
- {
- if (fCurrentIndex > fLowBound)
- --fCurrentIndex;
- else
- fCurrentIndex = kEmptyIndex;
- }
- }
-
- //--------------------------------------------------------------------------------------------------
- #pragma segment IteratorRes
-
- void CArrayIterator::DeleteElementAt(ArrayIndex theIndex,
- ArrayIndex theCount)
- {
- // tuck the endpoints of the iteration in to match
- if (theIndex < fLowBound)
- fLowBound -= theCount;
-
- if (theIndex <= fHighBound)
- fHighBound -= theCount;
-
- if (fIterateForward)
- {
- // If the deleted element was !in the range yet to be iterated
- // then bend the fCurrentIndex to account for it.
- if (theIndex <= fCurrentIndex)
- fCurrentIndex -= theCount;
- }
- else // Iterating backwards
- {
- // If the deleted element was IN the range yet to be iterated
- // then bend the fCurrentIndex to account for it.
- if (theIndex < fCurrentIndex)
- fCurrentIndex -= theCount;
- }
-
- // hand off control to the next link until you hit the last link in the circular chain
- if (fNextLink != fDynamicArray->fIteratorPtr)
- fNextLink->DeleteElementAt(theIndex, theCount);
- }
-
- //--------------------------------------------------------------------------------------------------
- #pragma segment IteratorRes
-
- void CArrayIterator::InsertElementBefore(ArrayIndex theIndex,
- ArrayIndex theCount)
- {
- // bump the endpoints of this iteration out to match
- if (theIndex <= fLowBound)
- fLowBound += theCount;
-
- if (theIndex <= fHighBound)
- fHighBound += theCount;
-
- if (fIterateForward)
- {
- // If the inserted element was !in the range yet to be
- // iterated then bend the fCurrentIndex to account for it.
- if (theIndex <= fCurrentIndex)
- fCurrentIndex += theCount;
- }
- else // Iterating backward
- {
- // If the inserted element was IN the range yet to be
- // iterated then bend the fCurrentIndex to account for it.
- if (theIndex < fCurrentIndex)
- fCurrentIndex += theCount;
- }
-
- // hand off control to the next link until you hit the last link in the circular chain
- if (fNextLink != fDynamicArray->fIteratorPtr)
- fNextLink->InsertElementBefore(theIndex, theCount);
- }
-
- //--------------------------------------------------------------------------------------------------
- #pragma segment IteratorRes
-
- pascal void CArrayIterator::HandleFailure(OSErr,
- long)
- {
- fDynamicArray->fIteratorPtr = this->RemoveFromList();
-
- // Check if there is a pending free request that couldn't be honored because we were
- // iterating and if so… be free!
- if (fDynamicArray->fFreeRequested &&!fDynamicArray->fIteratorPtr)
- fDynamicArray->Free();
-
- // the error will be resignalled automatically with the pascal style of failure handler
- }
-
- //--------------------------------------------------------------------------------------------------
- #pragma segment IteratorRes
-
- Boolean CArrayIterator::More(void)
- {
- return (fCurrentIndex != kEmptyIndex);
- }
-
- //--------------------------------------------------------------------------------------------------
- #pragma segment IteratorRes
-
- void CArrayIterator::Reset(void)
- {
- if (fIterateForward)
- fCurrentIndex = fLowBound;
- else
- fCurrentIndex = fHighBound;
- }
-
- //--------------------------------------------------------------------------------------------------
- #pragma segment IteratorRes
-
- CObjectIterator::CObjectIterator(TSortedList* itsList,
- ArrayIndex itsLowBound,
- ArrayIndex itsHighBound,
- Boolean itsForward) :
- CArrayIterator(itsList, itsLowBound, itsHighBound, itsForward)
- {
- }
-
- //--------------------------------------------------------------------------------------------------
- #pragma segment IteratorRes
-
- CObjectIterator::CObjectIterator(TSortedList* itsList,
- Boolean itsForward) :
- CArrayIterator(itsList, itsForward)
- {
- }
-
- //--------------------------------------------------------------------------------------------------
- #pragma segment IteratorRes
-
- CObjectIterator::CObjectIterator(TSortedList* itsList) :
- CArrayIterator(itsList)
- {
- }
-
- //--------------------------------------------------------------------------------------------------
- #pragma segment IteratorRes
-
- TObject* CObjectIterator::CurrentObject(void)
- {
- return ((TSortedList *)fDynamicArray)->At(fCurrentIndex);
- }
-
- //--------------------------------------------------------------------------------------------------
- #pragma segment IteratorRes
-
- TObject* CObjectIterator::FirstObject(void)
- {
- this->Reset();
- if (this->More())
- return ((TSortedList *)fDynamicArray)->At(fCurrentIndex);
- else
- return NULL;
- }
-
- //--------------------------------------------------------------------------------------------------
- #pragma segment IteratorRes
-
- TObject* CObjectIterator::NextObject(void)
- {
- this->Advance();
- if (this->More())
- return ((TSortedList *)fDynamicArray)->At(fCurrentIndex);
- else
- return NULL;
- }
-
- //--------------------------------------------------------------------------------------------------
- #pragma segment IteratorRes
-
- CHandleIterator::CHandleIterator(THandleList* itsHandleList,
- ArrayIndex itsLowBound,
- ArrayIndex itsHighBound,
- Boolean itsForward) :
- CArrayIterator(itsHandleList, itsLowBound, itsHighBound, itsForward)
- {
- }
-
- //--------------------------------------------------------------------------------------------------
- #pragma segment IteratorRes
-
- CHandleIterator::CHandleIterator(THandleList* itsHandleList,
- Boolean itsForward) :
- CArrayIterator(itsHandleList, itsForward)
- {
- }
-
- //--------------------------------------------------------------------------------------------------
- #pragma segment IteratorRes
-
- CHandleIterator::CHandleIterator(THandleList* itsHandleList) :
- CArrayIterator(itsHandleList)
- {
- }
-
- //--------------------------------------------------------------------------------------------------
- #pragma segment IteratorRes
-
- Handle CHandleIterator::CurrentHandle(void)
- {
- return ((THandleList *)fDynamicArray)->At(fCurrentIndex);
- }
-
- //--------------------------------------------------------------------------------------------------
- #pragma segment IteratorRes
-
- Handle CHandleIterator::FirstHandle(void)
- {
- this->Reset();
- if (this->More())
- return ((THandleList *)fDynamicArray)->At(fCurrentIndex);
- else
- return NULL;
- }
-
- //--------------------------------------------------------------------------------------------------
- #pragma segment IteratorRes
-
- Handle CHandleIterator::NextHandle(void)
- {
- this->Advance();
- if (this->More())
- return ((THandleList *)fDynamicArray)->At(fCurrentIndex);
- else
- return NULL;
- }
-
- //--------------------------------------------------------------------------------------------------
- #pragma segment IteratorRes
-
- CLongintIterator::CLongintIterator(TSortedLongintList* itsSortedLongintList,
- ArrayIndex itsLowBound,
- ArrayIndex itsHighBound,
- Boolean itsForward) :
- CArrayIterator(itsSortedLongintList, itsLowBound, itsHighBound, itsForward)
- {
- }
-
- //--------------------------------------------------------------------------------------------------
- #pragma segment IteratorRes
-
- CLongintIterator::CLongintIterator(TSortedLongintList* itsSortedLongintList,
- Boolean itsForward) :
- CArrayIterator(itsSortedLongintList, itsForward)
- {
- }
-
- //--------------------------------------------------------------------------------------------------
- #pragma segment IteratorRes
-
- CLongintIterator::CLongintIterator(TSortedLongintList* itsSortedLongintList) :
- CArrayIterator(itsSortedLongintList)
- {
- }
-
- //--------------------------------------------------------------------------------------------------
- #pragma segment IteratorRes
-
- long CLongintIterator::CurrentLong(void)
- {
- return ((TSortedLongintList *)fDynamicArray)->At(fCurrentIndex);
- }
-
- //--------------------------------------------------------------------------------------------------
- #pragma segment IteratorRes
-
- long CLongintIterator::FirstLong(void)
- {
- this->Reset();
- if (this->More())
- return ((TSortedLongintList *)fDynamicArray)->At(fCurrentIndex);
- else
- return NULL;
- }
-
- //--------------------------------------------------------------------------------------------------
- #pragma segment IteratorRes
-
- long CLongintIterator::NextLong(void)
- {
- this->Advance();
- if (this->More())
- return ((TSortedLongintList *)fDynamicArray)->At(fCurrentIndex);
- else
- return NULL;
- }
-
-